﻿/*
 * User: artem
 * Date: 27.04.2011
 * Time: 19:19
 */
using System;

using OOExp = Kernel.OpenOrganizerException;
using OOECode = Kernel.OpenOrganizerException.ErrorCode;

namespace Kernel
{
	/// <summary>
	/// Класс эвентов
	/// </summary>
	public class Event
	{
        private const int field_count = 9;

		private const int min_title_len = 3;
		private const int max_title_len = 50;
		private const int max_description_len = 300;
		
		private int id;
		
		private string title = @"Title";
		private EventType type = Event.EventType.Memo;
		private EventPeriodicity periodicty = Event.EventPeriodicity.None;		
		private string description = @"Description";
		private DateTime date = DateTime.Now;
	
		private DateTime start_notification;
		private DateTime end_notification;
		private UInt16 count_notification;

		public enum EventPeriodicity
		{
			None,
			EveryDay,
			EveryDayWithOutWeekends,
			EveryWeek,
			EveryMonth,
			EveryYear,
		}
		
		public enum EventType : byte
		{
			Meeting,
			Memo,
			Business,
			Impotant,
		}
		
		internal Event(object[] row)
		{
            if (row == null || row.Length != field_count)
                throw new OOExp(OOECode.IncorrectDataBase);
			
			this.id	= (int)row[0];
			this.title = (string)row[1];
			this.description = (string)row[2];
			this.type = 
                (EventType)Enum.Parse(typeof(EventType), 
                                      row[3].ToString());
			this.periodicty = 
                (EventPeriodicity)Enum.Parse(typeof(EventPeriodicity), 
                                             row[4].ToString());
			this.date = DateTime.Parse(row[5].ToString());
			this.start_notification = DateTime.Parse(row[6].ToString());
			this.end_notification = DateTime.Parse(row[7].ToString());
			this.count_notification = (ushort)(Int32)row[8];
		}
		
		public Event()
		{	}
		
		public int ID
		{	get { return id; }
			internal set { id = value; }
		}
		
		public string Title
		{	
			get
			{
				return title;
			}
			set
			{
				if (value == null)
                    throw new OOExp(OOECode.TitleCanNotBeEmpty);
				if (value.Length > max_description_len)
                    throw new OOExp(OOECode.TooLongTitle);
				if (value.Length < min_title_len)
                    throw new OOExp(OOECode.TooShortTitle);
				
				title = value;
			}
		}
		
		public EventType Type
		{
			get { return type; }
			set { type = value; }
		}
		
		public EventPeriodicity Periodicity
		{
			get { return periodicty; }
			set { periodicty = value; }
		}
		
		public string Description
		{
			get { return description; }
			set
			{
				if (value == null)
                    throw new OOExp(OOECode.DescriptionCanNotBeEmpty);
				if (value.Length > max_description_len)
                    throw new OOExp(OOECode.TooLongDescription);
				
				description = value;
			}
		}
		
		public DateTime Date
		{
			get { return date; }
			set
			{
				if (value < DateTime.Now)
                    throw new OOExp(OOECode.DateCanNotBePast);
				
				date = value;
			}
		}
		
		public DateTime NotificationStart
		{
			get { return start_notification; }
			set { start_notification = value; }
		}
		
		public DateTime NotificationEnd
		{
			get { return end_notification; }
			set { end_notification = value; }
		}
		
		public UInt16 NotificationCount
		{
			get { return count_notification; }
			set { count_notification = value; }
		}
		
		public string[] ToStringArray()
		{	
			string [] result = new string[field_count];
			
			result[0] = this.id.ToString();
			result[1] = this.title;
			result[2] = this.description;
			result[3] = this.type.ToString();
			result[4] = this.periodicty.ToString();
			result[5] = this.date.ToString();
			result[6] = this.start_notification.ToString();
			result[7] = this.end_notification.ToString();
			result[8] = this.count_notification.ToString();
			
			return result;
		}

        public override string ToString()
        {
            const string event_format = 
                "\nTitle : {0}\n" +
                "Date: {1} {2}\n" +
                "Type: {3}\n" +
                "Description: {4}\n";

            string result =  String.Format(event_format,
                                           title,
                                           date.ToLongDateString(),
                                           date.ToLongTimeString(),
                                           type.ToString(),
                                           description);
            
            return SeparateStringOnLine(result);
        }

        public static void AssertEvent(Event ev)
        {
            if (ev.start_notification > ev.end_notification)
                throw new OOExp(OOECode.InvalidNotificationInterval);
        }
        
        private static string SeparateStringOnLine(string str)
        {
        	const int line_len = 80;
        	const char new_line_marker = '\n';
        	const string new_line_sequence = "(->)\n";
        	const int cut_len = 75;
        	
        	string[] lines = str.Split(new_line_marker);
        	
        	string temp = "";
        	string result = "";
        	
        	foreach (var it in lines)
        	{
        		temp = it;
        		while (temp.Length > line_len)
        		{
        			result += temp.Substring(0, cut_len) +
        				new_line_sequence;
        			temp = temp.Substring(cut_len);
        		}
        		
        		result += temp + new_line_marker;
        	}
        	
        	return result;
        }
    }
}
